<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="index.js"></script>
</head>

<body>
    <span>没有防抖的input:</span> <input type="text" id="normal">
    <br>
    <span>（非立即执行）防抖的input:</span> <input type="text" id="d">
    <br>
    <span>（立即执行）防抖的input:</span> <input type="text" id="d2">

    <script>

        function logValue() {
            console.log(this.value);
        }
        // 没有防抖的input
        let normal = document.getElementById('normal');
        normal.addEventListener('keyup',logValue)

        // 防抖的input
        let d = document.getElementById('d');
        d.addEventListener('keyup',debounce(logValue,2000))

        // 防抖的input
        let d2 = document.getElementById('d2');
        d2.addEventListener('keyup',debounce_2(logValue,2000))
        /*
        所谓防抖，就是指触发事件后 n 秒后才执行函数，
        如果在 n 秒内又触发了事件，则会重新计算函数执行时间。
        */
        //非立即执行版本
        function debounce(func, delay) {
            let timeoutId;
            return function () {
                //let context = this;
                const args = [...arguments];
                if (timeoutId) {
                    clearTimeout(timeoutId);
                }
                //使用箭头函数可以解决this指向问题
                timeoutId = setTimeout(() => {
                    /* console.log(this); */
                    func.apply(this, args);
                    timeoutId = null;
                }, delay);
            }
        }
        //立即执行版本
        function debounce_2(func, delay) {
            let timeoutId;
            return function () {
                /* const context = this; */
                const args = [...arguments];
                /* 如果存在定时器，则清空计时器 */
                if (timeoutId) clearTimeout(timeoutId);
                /* 只有 timeoutId不存在时候，才会执行函数*/
                if (!timeoutId)  func.apply(this, args);
                /* 重新计时 */
                timeoutId = setTimeout(() => {
                    timeoutId = null;
                }, delay)
                
            }
        }
    </script>
</body>


</html>